
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
							   proc.h
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
													Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

typedef struct s_stackframe
{					/* proc_ptr points here				↑ Low			*/
	u32 gs;			/* ┓						│			*/
	u32 fs;			/* ┃						│			*/
	u32 es;			/* ┃						│			*/
	u32 ds;			/* ┃						│			*/
	u32 edi;		/* ┃						│			*/
	u32 esi;		/* ┣ pushed by save()				│			*/
	u32 ebp;		/* ┃						│			*/
	u32 kernel_esp; /* <- 'popad' will ignore it			│			*/
	u32 ebx;		/* ┃						↑栈从高地址往低地址增长*/
	u32 edx;		/* ┃						│			*/
	u32 ecx;		/* ┃						│			*/
	u32 eax;		/* ┛						│			*/
	u32 retaddr;	/* return address for assembly code save()	│			*/
	u32 eip;		/*  ┓						│			*/
	u32 cs;			/*  ┃						│			*/
	u32 eflags;		/*  ┣ these are pushed by CPU during interrupt	│			*/
	u32 esp;		/*  ┃						│			*/
	u32 ss;			/*  ┛						┷High			*/
} STACK_FRAME;

// 进程表或进程控制块，存放进程相关信息
typedef struct s_proc
{
	STACK_FRAME regs; /* process registers saved in stack frame */

	u16 ldt_sel;			   /* gdt selector giving ldt base and limit */
	DESCRIPTOR ldts[LDT_SIZE]; /* local descriptors for code and data */

	int ticks; /* remained ticks */
	int priority;
	int blocked;
	int sleeping;  // 运行耗时和休息都设为sleeping（其实不是个好的设计
	int ifrunning; // 判断是否有在运行，辅助普通程序输出

	int priorityNow; // 读写优先级(因通过PV操作实现，故统一为1，保留是为了防止饥饿进程)
	int blockedLast;

	u32 pid;		 /* process id passed in from MM */
	char p_name[16]; /* name of the process */

	int nr_tty;
} PROCESS;

typedef struct s_task
{
	task_f initial_eip;
	int stacksize;
	char name[32];
} TASK;

/* Number of tasks & procs */
#define NR_TASKS 1
#define NR_PROCS 6

typedef struct s_sema
{
	int value;
	int head;
	int tail;
	PROCESS *p_list[NR_PROCS]; // 等待信号量的进程列表
} SEMAPHORE;

/* stacks of tasks */
#define STACK_SIZE_TTY 0x8000
#define STACK_SIZE_TESTA 0x8000
#define STACK_SIZE_TESTB 0x8000
#define STACK_SIZE_TESTC 0x8000
#define STACK_SIZE_TESTD 0x8000
#define STACK_SIZE_TESTE 0x8000
#define STACK_SIZE_TESTF 0x8000

#define STACK_SIZE_TOTAL (STACK_SIZE_TTY +   \
						  STACK_SIZE_TESTA + \
						  STACK_SIZE_TESTB + \
						  STACK_SIZE_TESTC + \
						  STACK_SIZE_TESTD + \
						  STACK_SIZE_TESTE + \
						  STACK_SIZE_TESTF)
